package com.kwan.xframe.xbyte;

import android.graphics.Bitmap;
import android.graphics.Color;

import com.kwan.xframe.util.XBinaryReader;

/**
 * @author kwan
 * @date 2023/3/21 16:55
 * @Describe
 */
public class ByteUtils {

	public Bitmap bitmapFromByteArray(byte[] buf) {

		XBinaryReader br = new XBinaryReader(buf);
		int w = br.readInt32(); // 宽
		int h = br.readInt32(); // 高

		byte[] data = ByteArrayUtil.subBytes(buf, 9, buf.length - 9);
		Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
		for (int y = 0; y < h; ++y) {
			for (int x = 0; x < w; ++x) {
				bitmap.setPixel(x, y, getPixelFromMem(data, x, y, w));
			}
		}
		return bitmap;
	}


	//

	private int change(byte b) {

		//负数 补码 = 负数绝对值(正数) 符号位取反, 其余取反 +1

		//byte 取值范围 是 -128 到 127  一共255个值  而 一个 0 - 255的 可以表示 ARGB 的一个值

		//0000 0000 ~ 0111 1111 表示 0~127

		//1000 0000 比较特殊表示 -128， 因为0已经是有0000 0000 表示

		//1000 0001 ~ 1111 1111 表示 -127 ~ -1

		//在 Java中 byte型数据在内存中占8位，int型数据在内存中占32位。0xff默认为int型，是十六进制。
		//
		//0xFF: 0000 0000 | 0000 0000 | 0000 0000 | 1111 1111 = 255
		//当 byte & 0xFF 时，先将byte 转 int : 正数 高补0 ，负数高补 1 （高位补符号位）。然后再截断成 byte (只取后8位)。


		//byte i = 128; 编译错误

		//当定义byte i 为 128时， 编译错，根据上面的分析 byte 类型最大只支持到 127.

		//**128 :: 0000 0000 | 0000 0000 | 0000 0000 | 1000 0000 **
		//                         & (与操作)
		//0xFF ::  0000 0000 | 0000 0000 | 0000 0000  | 1111 1111
		//                         ↓↓
		//         0000 0000 | 0000 0000 | 0000 0000  | 1000 0000

		//  => 1000 0000 byte类型截断，只取后面8位。（1000 0000 即代表的是 -128）

		//对于 介于 0~127 的byte， 与上0xFF 即为其本来的值本身。


		//  byte ::   0 1 2 3 ... 127    -1   ... -128
		//  int  ::   0 1 2 3 ... 127    255  ...  128


		//对于负数byte
		//byte = -1, 即 1111 1111。
		//
		//byte = -1, 填充成 int : 1111 1111 | 1111 1111 | 1111 1111 | 1111 1111
		//
		//0XFF: 0000 0000 | 0000 0000 | 0000 0000 | 1111 1111
		//
		//      0000 0000 | 0000 0000 | 0000 0000 | 1111 1111   => 255


		//byte= -56, 即 11001000
		//
		//byte = -56, 填充成int：1111 1111 | 1111 1111 | 1111 1111 | 11001000
		//
		//0XFF: 0000 0000 | 0000 0000 | 0000 0000 | 1111 1111
		//
		//      0000 0000 | 0000 0000 | 0000 0000 | 1100 1000 => 200

		//比如负数-56补码：11001000 ，最高位1代表符号位。
		//
		//现在把对应的11001000，认为是一个正数，即无符号位数, 则变成 200。



		// byte & 0xFF : 将byte转化成一个0-255之间的数字，
		// 这个数字有可能不是原本的byte本身(因为负数的情况)。
		// 但是将转成的int强制类型转换为 byte 就又回去。（恢复成了原来的byte的值）

		return b & 0xff;
	}

	private int getPixelFromMem(byte[] buf, int x, int y, int w) {
		int idx = (w * y + x) * 4;
		//Timber.i(getPixelFromMem","a:"+buf[idx + 3]+" r:"+buf[idx + 2]+" g:"+buf[idx + 1]+" b:"+buf[idx]);
		return Color.argb(change(buf[idx + 3]), change(buf[idx + 2]), change(buf[idx + 1]), change(buf[idx]));
	}


}
